
Object.defineProperty(exports, "__esModule", { value: true });
/**
* @author: guojianbo
* @since: 2022-04-23 12:45:29
*/
var log_1 = __webpack_require__(/*! ../utils/log */ "./src/core/utils/log.ts");
var analytics_1 = __webpack_require__(/*! _util/analytics */ "./src/core/utils/analytics.ts");
var report_util_1 = __webpack_require__(/*! ./report-util */ "./src/core/statistics/report-util.ts");
var deviceInfo_1 = __webpack_require__(/*! ../utils/deviceInfo */ "./src/core/utils/deviceInfo.ts");
/*
登录阶段分为socket阶段和auth阶段，一次完整的登录过程只进行一次上报
所以只要用户认证信息上有效（假如是服务端返回错误、注销等场景下会造成用户认证信息失效），则会在sdk内部不断进行登录的上报
*/
var LoginReport = /** @class */ (function () {
    function LoginReport() {
        this._isReport = true; // 表示是否进行数据上报，只有用户的认证信息有效时才进行上报。假如是服务端返回错误、注销等场景下会造成用户认证信息失效则不应该进行上报
        // 保留最后3次的socket结果，模拟移动端的复合连接（每3个连接进行一次上报）上报。
        // socket失败上报的判断逻辑是连续socket三次失败则上报失败；只要最后一次socket是成功的则认为socket阶段成功然后在auth阶段上报的时候带上socket的成功上报信息
        this._socketArray = [];
        this._authStartTime = 0;
        this._socketFailReportCount = 0;
    }
    LoginReport.prototype.clearData = function () {
        this._socketArray = [];
        this._authStartTime = 0;
    };
    LoginReport.prototype.setRunReport = function (isReport) {
        this._isReport = isReport;
    };
    LoginReport.prototype.getSocketInfo = function (id) {
        var result = null;
        if (!this._socketArray) {
            return result;
        }
        this._socketArray.forEach(function (item) {
            if (item && id && item.id === id) {
                result = item;
            }
        });
        return result;
    };
    LoginReport.prototype.deleteSocketInfo = function (id) {
        if (!id || !this.getSocketInfo(id)) {
            return;
        }
        this._socketArray = this._socketArray.filter(function (item) {
            return item.id !== id;
        });
    };
    LoginReport.prototype.getLastSuccessSocketInfo = function () {
        if (!this._socketArray || this._socketArray.length <= 0) {
            return null;
        }
        var info = this._socketArray[this._socketArray.length - 1];
        return info.connectStatus === 'success' ? info : null;
    };
    LoginReport.prototype.getReportSocketInfo = function (bSuccess) {
        // bSuccess为true表示获取socket成功阶段的耗时
        // bSuccess为false表示获取socket失败阶段的耗时
        // socket成功阶段的耗时等于最后一次socket成功的耗时加上前两次失败的耗时
        // socket失败阶段的耗时等于最后三次socket失败的耗时
        if (!this._socketArray || this._socketArray.length <= 0) {
            return 0;
        }
        var result = {
            time: 0,
            connectTypes: ''
        };
        var totalTime = 0;
        var connectTypes = '';
        var lastInfo = this._socketArray[this._socketArray.length - 1];
        var maxSocketCount = 3;
        if ((bSuccess && lastInfo.connectStatus !== 'success')
            || (!bSuccess && lastInfo.connectStatus === 'success')) {
            return 0;
        }
        totalTime += (lastInfo.endTime - lastInfo.startTime);
        connectTypes += lastInfo.connectType;
        maxSocketCount--;
        for (var i = this._socketArray.length - 2; i >= 0; i--) {
            var info = this._socketArray[i];
            if (info.connectStatus === 'success' || maxSocketCount <= 0) {
                break;
            }
            totalTime += (info.endTime - info.startTime);
            connectTypes += ',' + info.connectType;
            maxSocketCount--;
        }
        result.time = totalTime > 16000 ? 16000 : totalTime; // 每隔4秒发起一个socket连接，最多16秒耗时
        return {
            time: totalTime,
            connectTypes: connectTypes
        };
    };
    LoginReport.prototype.isRunSocketErrorReport = function () {
        if (!this._isReport || !this._socketArray || this._socketArray.length < 3) {
            return false;
        }
        for (var i = 0; i < this._socketArray.length; i++) {
            var info = this._socketArray[i];
            if (info.connectStatus === 'success') {
                return false;
            }
        }
        return true;
    };
    LoginReport.prototype.reportSocketStart = function (_a) {
        var id = _a.id, connectType = _a.connectType;
        this.reportSocket({ connectStatus: 'init', id: id, connectType: connectType });
    };
    LoginReport.prototype.reportSocketSuccess = function (_a) {
        var id = _a.id;
        this.reportSocket({ connectStatus: 'success', id: id });
    };
    LoginReport.prototype.reportSocketFail = function (_a) {
        var id = _a.id;
        this.reportSocket({ connectStatus: 'fail', id: id });
    };
    LoginReport.prototype.reportSocketTimeout = function (_a) {
        var id = _a.id;
        this.reportSocket({ connectStatus: 'timeout', id: id });
    };
    LoginReport.prototype.reportSocket = function (_a) {
        var connectStatus = _a.connectStatus, id = _a.id, _b = _a.connectType, connectType = _b === void 0 ? '' : _b;
        try {
            if (!this._socketArray) {
                return;
            }
            if (connectStatus === 'init') {
                var info = {
                    id: id,
                    connectType: connectType,
                    startTime: Date.now(),
                    endTime: 0,
                    connectStatus: 'init',
                };
                if (this._socketArray.length >= 3) {
                    this._socketArray.shift();
                }
                this._socketArray.push(info);
            }
            else if (connectStatus === 'success' || connectStatus === 'fail' || connectStatus === 'timeout') {
                var info = this.getSocketInfo(id);
                if (!info || info.connectStatus !== 'init') {
                    return;
                }
                if (!deviceInfo_1.default.isHasNetwork() && connectStatus !== 'success') { // web端即使没有网络也会一直进行socket连接，因为web不能准确的感知网络状态，而移动在无网络的时候不会进行socket连接，所以参考移动类似的上报实现
                    this.deleteSocketInfo(id);
                    return;
                }
                info.endTime = Date.now();
                if (info.endTime <= info.startTime) { // 做个容错，防止出现异常数据
                    info.endTime = info.startTime;
                }
                if (info.endTime - info.startTime > 4000) {
                    info.endTime = info.startTime + 4000;
                }
                info.connectStatus = connectStatus;
                if (this.isRunSocketErrorReport()) {
                    this._socketFailReportCount++;
                    if (this._socketFailReportCount > 3) { // 由于web的特殊性判断不出网络的准确状态，所以在没有网络的时候也会一直连接，连续上报了3次失败则不再进行socket失败上报
                        return;
                    }
                    var socketReportInfo = this.getReportSocketInfo(false);
                    var reportData = {
                        nm: 'connect_ip',
                        val: {
                            result: 1,
                            msg: '',
                            socket_result: 1,
                            time: socketReportInfo.time,
                            socket_time: socketReportInfo.time,
                            net: report_util_1.REPORT_NET_TYPE,
                            status: deviceInfo_1.default.isHasNetwork() ? 0 : 1,
                            ids: socketReportInfo.connectTypes
                        },
                    };
                    analytics_1.default.report(reportData);
                    this.clearData();
                }
            }
            else {
                return;
            }
        }
        catch (error) {
            log_1.default.error('LoginReport::reportSocket error info:' + error);
        }
    };
    LoginReport.prototype.reportAuthStart = function () {
        try {
            if (!this.getLastSuccessSocketInfo()) {
                return;
            }
            this._socketFailReportCount = 0;
            this._authStartTime = Date.now();
        }
        catch (error) {
            log_1.default.error('LoginReport::reportAuthStart error info:' + error);
        }
    };
    LoginReport.prototype.reportAuthTimeout = function () {
        this.reportAuthEnd({ resultCode: 10001 });
    };
    LoginReport.prototype.reportAuthSuccess = function () {
        // 假如在认证过程中断开了网络连接认为认证成功（参考移动实现）
        // 假如服务端返回认证成功则认为认证成功
        this.reportAuthEnd({ resultCode: 0 });
    };
    LoginReport.prototype.reportAuthFail = function (_a) {
        var resultCode = _a.resultCode;
        this.reportAuthEnd({ resultCode: resultCode });
    };
    LoginReport.prototype.reportAuthEnd = function (_a) {
        var resultCode = _a.resultCode, _b = _a.errorMsg, errorMsg = _b === void 0 ? '' : _b;
        try {
            if (!this.getLastSuccessSocketInfo() || this._authStartTime === 0 || !this._isReport) {
                return;
            }
            var socketReportInfo = this.getReportSocketInfo(true);
            var authTime = Date.now() - this._authStartTime;
            if (authTime > 30000) {
                authTime = 30000;
            }
            var reportData = {
                nm: 'connect_ip',
                val: {
                    result: resultCode === 0 ? 0 : 1,
                    msg: errorMsg || '',
                    socket_result: 0,
                    login_result: resultCode,
                    time: socketReportInfo.time + authTime,
                    socket_time: socketReportInfo.time,
                    login_time: authTime,
                    net: report_util_1.REPORT_NET_TYPE,
                    status: deviceInfo_1.default.isHasNetwork() ? 0 : 1,
                    ids: socketReportInfo.connectTypes
                },
            };
            analytics_1.default.report(reportData);
            this.clearData();
        }
        catch (error) {
            log_1.default.error('LoginReport::reportAuthEnd error info:' + error);
        }
    };
    return LoginReport;
}());
exports.default = new LoginReport();


//# sourceURL=webpack://MTDX/./src/core/statistics/login-report.ts?